package com.kurumi.medical.util;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;

import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;


public class PDFUtil {

	private static URL url;
	private static HttpURLConnection con;
	private static int state = -1;

	public static List<String> pdfToImage(String pdfPath, String imagePath) {
		List<String> imagePathList = new ArrayList<>();
		File file = new File(pdfPath);
		BufferedImage image = null;
		PDDocument doc = null;
		PDFRenderer renderer = null;
		try {
			doc = PDDocument.load(file);
			renderer = new PDFRenderer(doc);
			int pageCount = doc.getNumberOfPages();
			for (int i = 0; i < pageCount; i++) {
				image = renderer.renderImage(i, 2.5f);
				String fileName= generateFileNameByTime()+".png";
				String imageFileNamePath = imagePath + fileName;
				ImageIO.write(image, "PNG", new File(imageFileNamePath));
				imagePathList.add(fileName);

			}
		} catch (IOException e) {
			return imagePathList = new ArrayList<>();
		} finally {
			if (renderer != null) {
				renderer = null;
			}
			if (doc != null) {
				try {
					doc.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (image != null) {
				image = null;
			}
		}
		return imagePathList;
	}

	/**
	 * 从网络Url中下载文件
	 * 
	 * @param urlStr
	 * @param fileName
	 * @param savePath
	 * @throws IOException
	 */
	public static String downLoadByUrl(String urlStr, String fileName, String savePath) throws IOException {
		URL url = null;
		InputStream inputStream = null;
		FileOutputStream fos = null;
		String pdfPath = null;
		HttpURLConnection conection = null;
		try {
			if (!isConnect(urlStr)) {
				return null;
			}
			url = new URL(urlStr);
			conection = (HttpURLConnection) url.openConnection();
			// 设置超时间为5秒
			conection.setConnectTimeout(5 * 1000);
			// 防止屏蔽程序抓取而返回403错误
			conection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
			// 得到输入流
			inputStream = conection.getInputStream();
			// 获取自己数组
			byte[] getData = readInputStream(inputStream);
			// 文件保存位置
			File saveDir = new File(savePath);
			if (!saveDir.exists()) {
				saveDir.mkdirs();
			}
			pdfPath = saveDir + File.separator + fileName;
			File file = new File(pdfPath);
			fos = new FileOutputStream(file);
			fos.write(getData);

			System.out.println("info:" + url + " download success");
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			if (fos != null) {
				fos.close();
			}
			if (inputStream != null)
				inputStream.close();
			try {
				if (null != conection) {
					conection.disconnect();
				}
			} catch (Exception e2) {
				// TODO: handle exception
			}
		}

		return pdfPath;
	}

	/**
	 * 功能：检测当前URL是否可连接或是否有效, 描述：最多连接网络 5 次, 如果 5 次都不成功，视为该地址不可用
	 * 
	 * @param urlStr
	 *            指定URL网络地址
	 * @return URL
	 */
	public static synchronized boolean isConnect(String urlStr) {
		int counts = 0;
		if (urlStr == null || urlStr.length() <= 0) {
			return false;
		}
		while (counts < 5) {
			try {
				url = new URL(urlStr);
				con = (HttpURLConnection) url.openConnection();
				state = con.getResponseCode();
				System.out.println(counts + "= " + state);
				if (state == 200) {
					System.out.println("URL可用！");
					return true;
				}
				break;
			} catch (Exception ex) {
				counts++;
				System.out.println("URL不可用，连接第 " + counts + " 次");
				urlStr = null;
				continue;
			}

		}
		return false;
	}

	/**
	 * 从输入流中获取字节数组
	 * 
	 * @param inputStream
	 * @return
	 * @throws IOException
	 */
	public static byte[] readInputStream(InputStream inputStream) throws IOException {
		byte[] buffer = new byte[1024];
		int len = 0;
		ByteArrayOutputStream bos = null;
		
		try {
			bos = new ByteArrayOutputStream();
			while ((len = inputStream.read(buffer)) != -1) {
				bos.write(buffer, 0, len);
			}
		} finally {
			if (null != bos) {
				bos.close();
			}
		}
		
		return bos.toByteArray();
	}

	public static Map<String, Object> pdfRecordSheet(String url,String fileLocalDir,String patientId, String visitNumber, String visitGuid,String suffix)
			throws IOException {
		Map<String, Object> temperatureMap = null;

		temperatureMap = new HashMap<>();
		String pdfRemoveurl = url+ patientId + "_" + visitNumber + "_"+ suffix+".pdf";
		String pdfFilePath = downLoadByUrl(pdfRemoveurl, patientId + "_" + visitNumber + "_"+ suffix+".pdf",
				fileLocalDir+suffix+"/" + visitGuid);
		if (StringUtils.isNotBlank(pdfFilePath)) {
			temperatureMap.put("sourceFilePath",patientId + "_" + visitNumber +"_"+ suffix+".pdf");
			List<String> imagePathList = pdfToImage(pdfFilePath,
					fileLocalDir+suffix+"/" + visitGuid + "/");
			temperatureMap.put("imageFilePathList", imagePathList);
		}

		return temperatureMap;

	}


	public static String generateFileNameByTime() {
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		return format.format(new Date());
	}

	/**
	 * 测试是否可以连通网址
	 * @param urlStr
	 * @return 200:成功，404：资源不存在，-1：网址错误或无法连接服务器
	 */
	public static synchronized int getConnectState(String urlStr) {
		int counts = 0;
		
		if (urlStr == null || urlStr.length() <= 0) {
			return -1;
		}
		
		while (counts < 5) {
			try {
				url = new URL(urlStr);
				con = (HttpURLConnection) url.openConnection();
				state = con.getResponseCode();
				System.out.println(counts + "= " + state);
				if (state == 200) {
					System.out.println("URL可用！");
					return 200;
				}
				break;
			} catch (IOException ex) {
				counts++;
				System.out.println("URL不可用，连接第 " + counts + " 次");
				if(counts == 5){
					return -1;
				}
				continue;
			}

		}
		
		return 404;
	}
	
	/**
	 * 下载网络资源
	 * @param fileUrl
	 * @param saveFileName
	 * @param saveFileParentPath
	 * @return 200:成功，404：资源不存在，-1：网址错误或无法连接服务器,500:获取资源内部错误
	 * @throws IOException
	 */
	public static int downLoadFileByFileUrl(String fileUrl, String saveFileName, String saveFileParentPath) throws IOException {
		int responseCode = -1;
		URL url = null;
		InputStream inputStream = null;
		FileOutputStream fos = null;
		String pdfPath = null;
		
		try {
			int connectionState = getConnectState(fileUrl);
			
			if (connectionState != 200) {
				responseCode = connectionState;
				return responseCode;
			}
			
			url = new URL(fileUrl);
			con = (HttpURLConnection) url.openConnection();
			// 设置超时间为5秒
			con.setConnectTimeout(5 * 1000);
			// 防止屏蔽程序抓取而返回403错误
			con.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
			// 得到输入流
			inputStream = con.getInputStream();
			// 获取自己数组
			byte[] getData = readInputStream(inputStream);
			// 文件保存位置
			File saveDir = new File(saveFileParentPath);
			
			if (!saveDir.exists()) {
				saveDir.mkdirs();
			}
			
			pdfPath = saveFileParentPath + File.separator + saveFileName;
			File file = new File(pdfPath);
			fos = new FileOutputStream(file);
			fos.write(getData);
			
			responseCode = 200;
		} catch (IOException ioE) {
			ioE.printStackTrace();
			responseCode = 500;
			throw ioE;
		} finally {
			IOUtils.closeQuietly(fos);
			IOUtils.closeQuietly(inputStream);
			con.disconnect();
		}

		return responseCode;
	}
	
	public static List<String> getImageFormImage(String pdfPath, String imagePath) throws IOException {
		List<String> imagePathList = new ArrayList<>();
		File file = new File(pdfPath);
		BufferedImage image = null;
		PDDocument doc = null;
		PDFRenderer renderer = null;
		
		try {
			doc = PDDocument.load(file);
			renderer = new PDFRenderer(doc);
			int pageCount = doc.getNumberOfPages();
			
			for (int i = 0; i < pageCount; i++) {
				image = renderer.renderImage(i, 2.5f);
				String fileName= generateFileNameByTime()+".png";
				String imageFileNamePath = imagePath + fileName;
				ImageIO.write(image, "PNG", new File(imageFileNamePath));
				
				imagePathList.add(fileName); 
			}
		} catch (IOException e) {
			throw e;
			
		} finally {
			if (renderer != null) {
				renderer = null;
			}
			if (doc != null) {
				try {
					doc.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (image != null) {
				image = null;
			}
		}
		return imagePathList;
	}
	
	/**
	 * 重复提取护理记录
	 * 
	 * @param pdfPath
	 * @param imagePath
	 * @param imageFileParentDir
	 * @return
	 * @throws IOException
	 */
	public static List<String> getImageFormImage(String pdfPath, String imagePath, String imageFileParentDir) throws IOException {
		List<String> imagePathList = new ArrayList<>();
		File file = new File(pdfPath);
		BufferedImage image = null;
		PDDocument doc = null;
		PDFRenderer renderer = null;
		try {
			doc = PDDocument.load(file);
			renderer = new PDFRenderer(doc);
			int pageCount = doc.getNumberOfPages();
			for (int i = 0; i < pageCount; i++) {
				image = renderer.renderImage(i, 2.5f);
				String fileName= generateFileNameByTime()+".png";
				String imageFileNamePath = imagePath + fileName;
				ImageIO.write(image, "PNG", new File(imageFileNamePath));
				//加上父目录
				imagePathList.add(imageFileParentDir + "/" + fileName);

			}
		} catch (IOException e) {
			throw e;
		} finally {
			if (renderer != null) {
				renderer = null;
			}
			if (doc != null) {
				try {
					doc.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (image != null) {
				image = null;
			}
		}
		return imagePathList;
	}
	
	/**
	 * 生成检验报告单 pdf
	 * @param list
	 * @param homePageTemplatePDFPath
	 * @param targetPath
	 */
	public static void getPdfByTemplate(List<Map<String,Object>> list,String homePageTemplatePDFPath,String targetPath) {
		PdfReader reader = null;
		OutputStream bos = null;
		PdfStamper stamper = null;
		
		try {
			reader = new PdfReader(homePageTemplatePDFPath);// 读取pdf模板
			bos = new FileOutputStream(new File(targetPath));
			stamper = new PdfStamper(reader, bos);
			AcroFields form = stamper.getAcroFields();

			// 使用中文字体
			BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
			ArrayList<BaseFont> fontList = new ArrayList<BaseFont>();
			fontList.add(bf);

			form.setSubstitutionFonts(fontList);
			
			for (int i = 0; i < list.size(); i++) {
				Map<String,Object> map = list.get(i);
				String time = "";
				if(map.get("reportDateTime")!=null){
					time=((String)map.get("reportDateTime")).substring(0, 10);
				}
				if(map.get("title")!=null){
					form.setField("title"+i,time + (String)map.get("title"));
				}
				
				form.setField("patientName"+i, (String)map.get("patientName"));
				form.setField("deptCategoryName"+i, (String)map.get("deptCategoryName"));
				form.setField("specimenCode"+i, (String)map.get("specimenCode"));
				form.setField("sexName"+i, (String)map.get("sexName"));
				form.setField("bedName"+i, (String)map.get("bedName"));
				form.setField("barCode"+i, (String)map.get("barCode"));
				form.setField("ageName"+i, (String)map.get("ageName"));
				form.setField("costName"+i, (String)map.get("costName"));
				form.setField("specimenTypeName"+i, (String)map.get("specimenTypeName"));
				form.setField("mrId"+i, (String)map.get("mrId"));
				form.setField("submittingPhysicianName"+i, (String)map.get("submittingPhysicianName"));
				form.setField("clinicalDiagnosisName"+i, (String)map.get("clinicalDiagnosisName"));
				form.setField("samplingDateTime"+i, (String)map.get("samplingDateTime"));
				form.setField("inspectDateTime"+i, (String)map.get("inspectDateTime"));
				form.setField("inspectionDoctorName"+i, (String)map.get("inspectionDoctorName"));
				form.setField("acceptanceCheckDateTime"+i, (String)map.get("acceptanceCheckDateTime"));
				form.setField("reportDateTime"+i, (String)map.get("reportDateTime"));
				form.setField("auditorDoctorName"+i, (String)map.get("auditorDoctorName"));
				form.setField("remark"+i, "本报告仅对监测标本负责");
				
				// {projectName=尿红细胞, examinationResult=6.60, examinationUnit=p/ul, examinationResultMark=↑, referenceValues=0--5}
				List<Map<String,Object>> examList = (List<Map<String, Object>>) map.get("examinationReportsItems");
				for (int j = 0; j < examList.size(); j++) {
					Map<String,Object> examMap = examList.get(j);
					form.setField("projectName"+i+j, (String)examMap.get("projectName"));
					form.setField("examinationResult"+i+j, (String)examMap.get("examinationResult")+"  "+(String)examMap.get("examinationResultMark"));
					form.setField("referenceValues"+i+j, (String)examMap.get("referenceValues"));
				}
			}
			
			stamper.setFormFlattening(true);// 如果为false那么生成的PDF文件还能编辑，一定要设为true
			stamper.close();
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (Exception e2) {
				}
			}
			if(bos!=null){
				try {
					bos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * pdf转换成图片
	 * 
	 * @param pdfPathList
	 * @param imagePath
	 * @return
	 */
	public static List<String> pdf2Image(List<String> pdfPathList, String imagePath) {
		List<String> imagePathList = new ArrayList<>();
		
		for (String pdfPath : pdfPathList) {
			File file = new File(pdfPath);
			BufferedImage image = null;
			PDDocument doc = null;
			PDFRenderer renderer = null;
			try {
				doc = PDDocument.load(file);
				renderer = new PDFRenderer(doc);
				int pageCount = doc.getNumberOfPages();
				for (int i = 0; i < pageCount; i++) {
					image = renderer.renderImage(i, 2.5f);
					//String fileName= generateFileNameByTime()+".png";
					String fileName = "";
					try {
						fileName = StringUtil.getTimeId() + ".png";
					} catch (Exception e) {
						e.printStackTrace();
					}
					String imageFileNamePath = imagePath + fileName;
					ImageIO.write(image, "PNG", new File(imageFileNamePath));
					imagePathList.add(fileName);
				}
			} catch (IOException e) {
				return imagePathList = new ArrayList<>();
			} finally {
				if (renderer != null) {
					renderer = null;
				}
				if (doc != null) {
					try {
						doc.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				if (image != null) {
					image = null;
				}
			}
		}
		return imagePathList;
	}
	
	
	
	
}




